package com.gitee.swsk33.publishsubscribereactordemo;

import com.gitee.swsk33.publishsubscribereactordemo.model.Event;
import com.gitee.swsk33.publishsubscribereactordemo.model.publisher.GateKeeper;
import com.gitee.swsk33.publishsubscribereactordemo.model.subscriber.StudentPlayingGame;
import com.gitee.swsk33.publishsubscribereactordemo.model.subscriber.StudentWatchingTV;
import reactor.core.publisher.BaseSubscriber;
import reactor.core.publisher.Flux;

/**
 * 主类客户端调用<br>
 * 不定期发布的场景
 */
public class IrregularPublish {

	public static void main(String[] args) throws Exception {
		// 两个看门的同学，一个看老师，一个看院长（具体发布者）
		GateKeeper teacherWatcher = new GateKeeper();
		GateKeeper deanWatcher = new GateKeeper();
		// Flux对象，用于传递事件给订阅者
		// “老师”话题发布者
		Flux<Event<String>> teacherFlux = Flux.create(sink -> {
			// create方法编写发布元素的逻辑，sink参数是FluxSink类型对象，用于操纵元素的发布等等
			// 这里先把sink传递给具体发布者即可，后续具体发布者再调用sink发布元素
			teacherWatcher.setupSink(sink);
		});
		// “院长”话题发布者
		Flux<Event<String>> deanFlux = Flux.create(sink -> {
			deanWatcher.setupSink(sink);
		});
		// 两个订阅者
		BaseSubscriber<Event<String>> tvStudent = new StudentWatchingTV("小吴", "甄嬛传");
		BaseSubscriber<Event<String>> gameStudent = new StudentPlayingGame("小李", "原神");
		// 一个订阅“老师”话题，一个订阅“院长”话题
		teacherFlux.subscribe(tvStudent);
		deanFlux.subscribe(gameStudent);
		// 延迟一小段时间
		System.out.println("大家正在摸鱼...");
		Thread.sleep(1000);
		// 发布消息
		teacherWatcher.publish(new Event<>("teacher", "张老师正在走廊上"));
		System.out.println("老师走了，继续摸鱼...");
		Thread.sleep(800);
		deanWatcher.publish(new Event<>("dean", "院长已经来研究室门口看着了"));
	}

}